package SpiderController;

##########################
#     OmnibusProxy       #
#    Krzysztof Ulman     #
# Politechnika Krakowska #
#      Kraków 2012       #
##########################

use strict;
use warnings;
use encoding 'utf8';

use AppConfig;
use Screen;

#sekundy, czas zwloki pomiedzy kolejnymi requestami
our $INTERVAL;

#sekundy, czas zwloki ustawiony raz na N zapytan
our $BIG_INTERVAL;

#globalny licznik do celow statystycznych
our $totalDownloaded = 0;

##co ile zapytan robic duza przerwe
#our $SPIDER_N;

#czas pobrania poprzedniej strony
#my $lastAccessTime;

#licznik pobranych stron
#my $pageCounter;

#licznik wykorzystania przegladarki
#my $browserUsageCounter;

#co ile zadan wymieniac obiekt brzegladarki
#my $browserReplacementCounter;

#wylosowana wartosc, co ile zapytan powinno sie zrobic dluzsza przerwe
#my $spiderN;

#konstruktor
#klasa odpowiedzialna za zarzadzanie przerwami pomiedzy poszczegolnymi zapytaniami
sub new {
	shift;
	my $searcherId = shift;
	my $self = {};
	bless $self;
	
	#poczatkowa wartosc przerwy
	if(!$INTERVAL) {
		$INTERVAL = AppConfig->getProperty('SPIDER_INTERVAL');
		$BIG_INTERVAL = AppConfig->getProperty('SPIDER_BIG_INTERVAL');
		Screen->printAndLogInfo("INTERVAL: $INTERVAL [s] \tBIG_INTERVAL: $BIG_INTERVAL");
	}
	
	$self->{searcherId} = $searcherId;
	$self->{pageCounter} = 1;
	$self->{pageCounterForSpiderN} = 1;
	$self->{lastAccessTime} = time - $INTERVAL;
	
	private_computeBrowserReplacementCounter($self);
	private_computeSpiderNValue($self);
	
	return $self;
}

#zarzadza przerwa pomiedzy kolejnymi zapytaniami
sub doInterval {
	my $self = shift;
	my $pageCounter = $self->{pageCounter}++;
	my $pageCounterForSpiderN = $self->{pageCounterForSpiderN}++;
	my $lastAccessTime = $self->{lastAccessTime};
	my $spiderN = $self->{spiderN};

	#obliczenie liczby sekund od ostatniego zapytania
	my $diff = time - $lastAccessTime;	
	if($diff < $INTERVAL) {
		my $toSleepTime = int(rand(2 * $INTERVAL));
		$toSleepTime -= $diff;
		if($toSleepTime <= 0) {
			$toSleepTime = 1;
		}
		sleep($toSleepTime);
	}
	
	#dodatkowa przerwa raz na SPIDER_N zapytan
	if($pageCounterForSpiderN % $spiderN == 0) {
		$self->{pageCounterForSpiderN} = 1;
		my $sleepTime = int(rand(2 * $BIG_INTERVAL));
		if($sleepTime < 1) {
			$sleepTime = 1;
		}
		Screen->printAndLogDebug("Dodatkowa przerwa na $sleepTime sekund...");
		sleep($sleepTime);
		private_computeSpiderNValue($self);
	}
	
	private_additionalLog($self);
	
	incrementTotalDownloaded();
	
	#zapisanie nowego czasu
	$self->{lastAccessTime} = time;
}

#zapisanie dodatkowych informacji
sub private_additionalLog {
	my $self = shift;
	my $searcherId = $self->{searcherId};
	Screen->additionalLog('ID:' . $searcherId . ';TIME:' . time . ';REPLACEMENT:' . $self->{browserReplacement});
	$self->{browserReplacement} = 0; #tylko raz logujemy
}

#zwraca liczbe pobranych stron
sub getPageCounter {
	my $self = shift;
	return $self->{pageCounter};
}

#zwieksza licznik o jeden
sub incrementPageCounter {
	my $self = shift;
	$self->{pageCounter}++;	
}

#czy nalezy wymienic obiekt przegladarki na inny
sub needBrowserReplacement {
	my $self = shift;
	#ile razy wykozystano juz istniejacy obiekt
	my $browserUsageCounter = $self->{browserUsageCounter};
	#ile razy moze byc wykorzystany istniejacy obiekt
	my $browserReplacementCounter = $self->{browserReplacementCounter};
	if($browserUsageCounter % $browserReplacementCounter == 0) {
		private_computeBrowserReplacementCounter($self);
		$self->{browserReplacement} = 1; #do celow statystycznych
		#zwrocenie TRUE
		return 1;
	} else {
		#inkrementacja
		$browserUsageCounter++;
		$self->{browserUsageCounter} = $browserUsageCounter;
		$self->{browserReplacement} = 0; #do celow statystyczych
		return 0;
	}
}

#losuje odpowiednie wartosci dla browserReplacementCounter
sub private_computeBrowserReplacementCounter {
	my $self = shift;
	
	#wyzerowanie licznika
	$self->{browserUsageCounter} = 1;
	
	#odczytanie wartosci z konfiguracji
	my $min = AppConfig->getProperty('BROWSER_REPLACEMENT_COUNTER_MIN'); 
	my $max = AppConfig->getProperty('BROWSER_REPLACEMENT_COUNTER_MAX');
	#i wylosowanie wartosci z podanego przedzialu 
	my $browserReplacementCounter = int(rand($max - $min)) + $min;
	$self->{browserReplacementCounter} = $browserReplacementCounter;
	Screen->printAndLogDebug('Browser replacement = ' . $browserReplacementCounter);
}

#losuje wartosci dla SPIDER_N
sub private_computeSpiderNValue {
	my $self = shift;
	#podobnie losujemy wartość dla $spiderN
	my $spiderNDb = AppConfig->getProperty('SPIDER_N');
	my $spiderN = int(rand(2 * $spiderNDb));
	if($spiderN < 2) {
		$spiderN = 2;
	}
	$self->{spiderN} = $spiderN;
#	Screen->printAndLogDebug('spiderN = ' . $spiderN);
}

sub getTotalDownloaded {
	return $totalDownloaded;
}

sub incrementTotalDownloaded {
	$totalDownloaded++;
}

1;